package org.ucas.kgraph.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.ucas.kgraph.dto.AccountDto;
import org.ucas.kgraph.dto.CarryDto;
import org.ucas.kgraph.dto.ErrDto;
import org.ucas.kgraph.dto.FileDto;
import org.ucas.kgraph.dto.ListDto;
import org.ucas.kgraph.dto.PermDto;
import org.ucas.kgraph.dto.ProfileDto;
import org.ucas.kgraph.dto.ResponseDto;
import org.ucas.kgraph.dto.UserDto;
import org.ucas.kgraph.entity.Account;
import org.ucas.kgraph.entity.Company;
import org.ucas.kgraph.entity.Perm;
import org.ucas.kgraph.entity.Role;
import org.ucas.kgraph.entity.UserProfile;
import org.ucas.kgraph.service.RoleService;
import org.ucas.kgraph.service.TermService;
import org.ucas.kgraph.service.UserService;
import org.ucas.kgraph.utils.common.DigestUtil;
import org.ucas.kgraph.utils.common.EncodeUtil;
import org.ucas.kgraph.utils.common.MsgService;
import org.ucas.kgraph.utils.exception.ForbiddenException;
import org.ucas.kgraph.utils.exception.NotFoundException;

import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.Random;




@Controller
@ResponseBody
public class UserController extends BaseController{

	

  @Autowired
  private UserService userService;	

  @Autowired
  private RoleService roleService;		

  
  @RequestMapping(value = "/sendMsg",method = RequestMethod.POST)
  public ResponseDto sendMsg(@RequestParam("telenumber") String telenumber) throws IOException{
	String sn="SDK-BBX-010-20610";
	String pwd="25a@f50b";
	MsgService mService=new MsgService(sn,pwd);
	Random random = new Random();
	int code = random.nextInt(899999);
	code = code+100000;
	String contentcode=java.net.URLEncoder.encode("您获取的验证码为["+code+"]",  "utf-8");
	code(code+"");
	telenumber(telenumber);
	String result_mt = mService.mdsmssend(telenumber, contentcode, "", "", "", "");		
    return ResponseDto.OK;
  }
  
  @RequestMapping(value = "/users",method = RequestMethod.POST)
  public ResponseDto register(@RequestParam("account") String name,
                              @RequestParam("password") String plainPassword,
                              @RequestParam("content") String contentCurr,
                              @RequestParam("com_id") String com_id
                              ){
    Account account = new Account();
    account.setName(name);
    account.setPlainPassword(plainPassword);
    if(contentCurr.equals(code())&&name.equals(telenumber())){
    }else{
		throw ForbiddenException.WRONG_CODE;
	}
    account.setRoleList(userService.getRoles("普通用户"));
    userService.create(account,com_id);
    userService.admlogin(account);
    return ResponseDto.OK;

  }
  
  @RequestMapping(value = "/users/com",method = RequestMethod.POST)
  public ResponseDto comregister(@RequestParam("account") String name,
                              @RequestParam("password") String plainPassword,
                              @RequestParam("content") String contentCurr,
                              @RequestParam("comname") String comname
                              ){
    Account account = new Account();
    account.setName(name);
    account.setPlainPassword(plainPassword);
    if(contentCurr.equals(code())&&name.equals(telenumber())){
    }else{
		throw ForbiddenException.WRONG_CODE;
	}
    account.setRoleList(userService.getRoles("管理员"));
    Company company = new Company();
    userService.createCompany(account,comname);
    return ResponseDto.OK;
  }
  
  @RequestMapping(value = "/users/getId",method = RequestMethod.POST)
  public CarryDto<AccountDto> getId(){
    Optional<Account> account;
    account=userService.findBySessionName();
    return CarryDto.of(AccountDto.of(account.get()));
  }
  @RequestMapping(value = "/users/getPermList",method = RequestMethod.POST)
  public ListDto<PermDto> getPermList(){
    Optional<Account> account;
    account=userService.findBySessionName();
    return ListDto.of(account.get().getRoleList().get(0).getPermList(),PermDto::of);
  }
  @RequestMapping(value = "/users/isAdmin",method = RequestMethod.POST)
  public ResponseDto getIsAdmin(){
    Optional<Account> account;
    account=userService.findBySessionName();
    for(int j = 0;j<account.get().getRoleList().size();j++){
    	List<Perm> permList = account.get().getRoleList().get(j).getPermList();
    	for(int i = 0;i<permList.size();i++){
    		if(permList.get(i).getName().equals("admin")){
    			ResponseDto tmpOK = new ResponseDto(HttpStatus.OK,"admin");
    			return tmpOK;
    		}
    	}
    }
    ResponseDto tmpOK = new ResponseDto(HttpStatus.OK,"user");
    return tmpOK;
  }
  
  @RequestMapping(value = "/users/getUserInfo",method = RequestMethod.POST)
  public CarryDto<UserDto> getUserInfo(){
    Optional<Account> account;
    account=userService.findBySessionName();
    return CarryDto.of(UserDto.oflist(account.get()));

  }
  
  @RequestMapping(value = "/logout",method = RequestMethod.GET)
  public ResponseDto logout(){
    subject().logout();
    return ResponseDto.OK;
  }
  
  
  @RequestMapping(value = "/login",method = RequestMethod.POST)
  public ResponseDto login(@RequestParam("account") String name,
                           @RequestParam("password") String plainPassword
                           ){
    Account account = new Account();
    account.setName(name);
    account.setPlainPassword(plainPassword);
    if(!isLogin()){ 
        userService.login(account);
    }
    Optional<Account> accountTmp;
    accountTmp=userService.findBySessionName();
    accountTmp.get().getRolesName().toString();
    for(int j = 0;j<accountTmp.get().getRoleList().size();j++){
    	List<Perm> permList = accountTmp.get().getRoleList().get(j).getPermList();
    	for(int i = 0;i<permList.size();i++){
    		if(permList.get(i).getName().equals("admin")){
    			ResponseDto tmpOK = new ResponseDto(HttpStatus.OK,"admin");
    		    return tmpOK;
    		}
    	}
    }
    ResponseDto tmpOK = new ResponseDto(HttpStatus.OK,"user");
    return tmpOK;
  }
  
  @RequiresAuthentication
  @RequestMapping(value = "/users/me",method = RequestMethod.DELETE)
  public ResponseDto disable(){
    userService.disable(principal().id);
    return ResponseDto.OK;
  }

  @RequestMapping(value = "/users/{id:\\d+}/profiles",method = RequestMethod.GET)
  public ProfileDto getProfile(@PathVariable  Long accountId){
    Optional<UserProfile> profile = userService.profile(accountId);
    if(!profile.isPresent()) throw NotFoundException.User_NotExists;
    return ProfileDto.of(profile.get());
  }
  
  
  @RequestMapping(value = "/users/list",method = RequestMethod.GET)
  public ListDto<FileDto> users(){
	  return (ListDto<FileDto>) ListDto.of(userService.getAllUsers(),UserDto::oflist);
  }
  
  @RequestMapping(value = "/users/editPassword",method = RequestMethod.PUT)
  public ResponseDto usersRePassword(@RequestParam("old_password") String opassword,@RequestParam("new_password") String npassword){
	  Optional<Account> account;
	  account=userService.findBySessionName();
	  userService.newpassword(account.get(),opassword,npassword);
	  return ResponseDto.OK;
  }
  @RequestMapping(value = "/users/findpass",method = RequestMethod.POST)
  public ResponseDto findpass(@RequestParam("account") String name,
          @RequestParam("content") String contentCurr) throws IOException{
	  if(contentCurr.equals(code())&&name.equals(telenumber())){
	  }else{
		  throw ForbiddenException.WRONG_CODE;
	  }
	  Optional<Account> account;
	  account=userService.findByName(name);
	  String sn="SDK-BBX-010-20610";
	  String pwd="25a@f50b";
	  MsgService mService=new MsgService(sn,pwd);
	  String base = "abcdefghijklmnopqrstuvwxyz0123456789";   
	    Random random = new Random();   
	    StringBuffer sb = new StringBuffer();   
	    for (int i = 0; i < 6; i++) {   
	        int number = random.nextInt(base.length());   
	        sb.append(base.charAt(number));   
	   }   
	  String contentcode=java.net.URLEncoder.encode("您的新密码为["+sb.toString()+"]",  "utf-8");
	  String result_mt = mService.mdsmssend(name, contentcode, "", "", "", "");
	  userService.findpassword(account.get(),String.valueOf(sb.toString()));
	  return ResponseDto.OK;
  }
  
  @RequestMapping(value = "/users/{id:\\d+}/editRole",method = RequestMethod.PUT)
  public ResponseDto usersReRole(@PathVariable  Long id,@RequestParam("roleName") String roleName){
	  Optional<Account> account = userService.load(id);
	  List<Role> roleList=roleService.findByName(roleName);
	  account.get().setRoleList(roleList);
	  userService.save(account);
	  return ResponseDto.OK;
  }
  @RequestMapping(value = "/users/{id:\\d+}/editUserInfo",method = RequestMethod.PUT)
  public ResponseDto usersReUserInfo(@PathVariable  Long id,@RequestParam("com_name") String com_name,@RequestParam("com_id") String com_id,@RequestParam("user_name") String user_name,@RequestParam("tele_num") String tele_num){
	  Optional<Account> account = userService.load(id);
	  if(!com_name.equals(null)){
		  account.get().getUserProfile().getCompany().setCom_name(com_name);
	  }
	  if(!com_id.equals(null)){
		  account.get().getUserProfile().getCompany().setCom_id(com_id);;
	  }
	  if(!user_name.equals(null)){
		  account.get().getUserProfile().setName(user_name);
	  }
	  if(!tele_num.equals(null)){
		  account.get().setName(tele_num);
	  }
	  userService.editUserInfo(account);
	  Subject subject = SecurityUtils.getSubject();
	  Session session =  subject.getSession();
	  session.setAttribute("userName", account.get().getName());
	  return ResponseDto.OK;
  }
  
  @RequestMapping(value = "/users/editUserName",method = RequestMethod.PUT)
  public ResponseDto usersReUserName(@RequestParam("user_name") String user_name){
	  Optional<Account> account;
	  account=userService.findBySessionName();
	  if(!user_name.equals(null)){
		  account.get().getUserProfile().setName(user_name);
	  }
	  userService.editUserInfo(account);
	  Subject subject = SecurityUtils.getSubject();
	  Session session =  subject.getSession();
	  session.setAttribute("userName", account.get().getName());
	  return ResponseDto.OK;
  }
  
  
  
  @RequestMapping(value = "/users/{id:\\d+}/editDisable",method = RequestMethod.PUT)
  public ResponseDto usersReDisable(@PathVariable  Long id,@RequestParam("state") String newState){
	  
	  if(newState.equals("0")){
		  userService.active(id);
	  }else{
		  userService.disable(id);
	  }
	  return ResponseDto.OK;
  }
  @RequestMapping(value = "/users/{id:\\d+}/delete",method = RequestMethod.DELETE)
  public ResponseDto usersDelete(@PathVariable  Long id){

	  userService.delete(id);
	  return ResponseDto.OK;
  }
  
  
  @RequiresAuthentication
  @RequestMapping(value = "/users/me/profiles",method = RequestMethod.GET)
  public ProfileDto meProfile(){
    return ProfileDto.of(profile());
  }

  @RequiresAuthentication
  @RequestMapping(value = "/users/me/profiles",method = RequestMethod.PUT)
  public ProfileDto editProfile(ProfileDto dto){
    UserProfile profile = profile();
    dto.writeTo(profile);
    userService.update(profile);
    return ProfileDto.of(profile);
  }

  @RequiresAuthentication
  @RequestMapping(value = "/users/me/changePassword",method = RequestMethod.PUT)
  public ResponseDto changePassword(@RequestParam("password") String oldPassword,
                                    @RequestParam String newPassword){
    Account account = current();
    account.setPlainPassword(oldPassword);
    if(userService.verify(account)){
      userService.changePassword(principal().id,newPassword);
      return ResponseDto.OK;
    }else
      throw ForbiddenException.WRONG_TOKEN;
  }

}
